import DebounceSelect from '@/components/DebounceSelect';
import type { InventoryHistoryRecord } from '@/DatabaseType/InventoryHistory';
import {
  InventoryHistoryType,
  InventoryHistoryTypeMap,
  ReverseType,
} from '@/DatabaseType/InventoryHistory';
import { useBrandFetchOptions } from '@/hooks/business/useFetchOptions';
import {
  addInventoryHistory,
  deleteInventoryHistory,
  getInventoryHistoryList,
  updateInventoryHistory,
} from '@/services/inventoryHistory';
import { shouldUpdateDependencies } from '@/utils/antd';
import {
  DEFAULT_REQUIRED_RULE,
  IMAGE_FALL_BACK,
  MODAL_TITLE_MAP,
} from '@/constant';
import { calcInventoryStock, stockIsUnsigned } from '@/utils/isUnsigned';
import { fen2yuan, yuan2fen } from '@/utils/money';
import { ResponseCode } from '@/utils/request';
import { PlusOutlined } from '@ant-design/icons';
import type { ActionType, ProColumns } from '@ant-design/pro-components';
import { PageContainer, ProTable } from '@ant-design/pro-components';
import {
  Button,
  Form,
  Image,
  Input,
  InputNumber,
  message,
  Modal,
  notification,
  Popconfirm,
  Radio,
  Space,
  Tag,
} from 'antd';
import type { SortOrder } from 'antd/lib/table/interface';
import { useRef, useState } from 'react';

function getSafeYuan(num: any) {
  try {
    return fen2yuan(num);
  } catch (error) {
    return undefined;
  }
}

function getSafeFen(num: number) {
  try {
    return yuan2fen(num);
  } catch (error) {
    return undefined;
  }
}

const InventoryHistoryManagement = () => {
  const actionRef = useRef<ActionType>();
  const [modalConfig, setModalConfig] = useState<{
    visible: boolean;
    type: 'edit' | 'view' | 'add';
    recordId?: number;
  }>({
    visible: false,
    type: 'add',
  });
  const [formInstance] = Form.useForm();
  const [operateLoading, setOperateLoadingLoading] = useState(false);

  const fetchBrandList = useBrandFetchOptions();

  const columns: ProColumns<InventoryHistoryRecord>[] = [
    {
      title: '主键',
      dataIndex: 'id',
      width: 75,
      align: 'center',
    },
    {
      title: '品牌实时信息',
      dataIndex: 'band',
      width: 200,
      render(dom, { brand }) {
        if (!brand) return '-';
        const marketPrice = getSafeYuan(brand.marketPrice);
        return (
          <Space>
            <Image
              style={{ objectFit: 'contain' }}
              width={60}
              height={60}
              src={brand.coverUrl || IMAGE_FALL_BACK}
              alt="coverUrl"
              fallback={IMAGE_FALL_BACK}
            />
            <div
              className="att-box"
              style={{ color: 'rgba(0,0,0, 0.75)', fontSize: 10 }}
            >
              <div>名称：{brand.name}</div>
              <div>
                市场单价：{marketPrice !== undefined ? marketPrice : '-'}
              </div>
              <div>库存：{brand.stock !== undefined ? brand.stock : '-'}</div>
            </div>
          </Space>
        );
      },
      formItemProps: { label: '品牌信息' },
      renderFormItem() {
        return (
          <Form.Item name="brandId" noStyle>
            <DebounceSelect fetchOptions={fetchBrandList} showArrow={false} />
          </Form.Item>
        );
      },
    },
    {
      title: '类型',
      dataIndex: 'type',
      render(dom, { type }) {
        const config = InventoryHistoryTypeMap[type];
        return <Tag color={config.status}>{config.text}</Tag>;
      },
      valueEnum: InventoryHistoryTypeMap,
    },
    {
      title: '数量',
      dataIndex: 'nub',
      render(dom, { nub }) {
        return nub;
      },
      search: false,
    },
    {
      title: '总价格',
      dataIndex: 'price',
      render(dom, { price }) {
        return getSafeYuan(price) || '-';
      },
      search: false,
    },
    {
      title: '市场单价',
      dataIndex: 'marketPrice',
      render(dom, { marketPrice }) {
        return getSafeYuan(marketPrice) || '-';
      },
      search: false,
    },
    {
      title: '描述',
      dataIndex: 'description',
      ellipsis: true,
      width: 200,
      search: false,
    },
    {
      title: '创建时间',
      dataIndex: 'createTime',
      valueType: 'dateTime',
      sorter: true,
    },
    {
      title: '更新时间',
      dataIndex: 'updateTime',
      valueType: 'dateTime',
      hideInSearch: true,
    },
    {
      title: '操作',
      valueType: 'option',
      fixed: 'right',
      render: (
        text,
        { id, marketPrice, type, nub, price, description, brandId, brand },
      ) => {
        const canBeToDelete = stockIsUnsigned(
          brand.stock,
          ReverseType[type],
          nub,
        );
        return [
          <a
            key="edit-detail"
            onClick={() => {
              // 打开弹窗
              setModalConfig((config) => ({
                ...config,
                visible: true,
                type: 'edit',
                recordId: id,
              }));
              formInstance.setFieldsValue({
                marketPrice: getSafeYuan(marketPrice),
                price: getSafeYuan(price),
                description,
                brandId,
                type,
                nub,
                // 除去本次的库存增减
                lastBrandStock: calcInventoryStock(
                  brand.stock,
                  ReverseType[type],
                  nub,
                ),
              });
            }}
          >
            编辑
          </a>,
          <Popconfirm
            key="delete-detail"
            title="确认删除该记录吗？"
            okText="是"
            cancelText="否"
            onConfirm={() => sureDelete(id)}
            disabled={!canBeToDelete}
          >
            <a
              href="#"
              style={{
                color: !canBeToDelete ? 'rgba(0, 0, 0, 0.25)' : undefined,
              }}
            >
              删除
            </a>
          </Popconfirm>,
        ];
      },
    },
  ];

  // 确认删除
  async function sureDelete(id: number) {
    try {
      const { code, message: msg } = await deleteInventoryHistory(id);
      if (code === ResponseCode.Success) {
        notification.success({ message: '删除成功' });
        actionRef.current?.reload();
      } else {
        notification.error({ message: msg || '删除失败' });
      }
    } catch (error: any) {
      notification.error({ message: error?.message || '删除品牌失败' });
    }
  }

  // proTable 获取角色列表方法
  async function request(params: any, sort: Record<string, SortOrder>) {
    const sortResult: any = {};
    const sortKeys = Object.keys(sort);
    sortResult.sortField = sortKeys[0];
    sortResult.sortType = sort[sortKeys[0]]?.replace('end', '').toUpperCase();
    try {
      const {
        code,
        data,
        message: msg,
      } = await getInventoryHistoryList({ ...params, ...sortResult });
      if (code === ResponseCode.Success) {
        return {
          data: data.list,
          total: data.total,
        };
      }
      throw new Error(msg);
    } catch (error: any) {
      message.error(error?.message);
      return {
        data: [],
        total: 0,
      };
    }
  }

  // 弹窗点击确认，提交表单
  async function sureAdd() {
    switch (modalConfig.type) {
      // 新增时
      case 'add': {
        // 获取表单数据
        const formData = await formInstance.validateFields();
        formData.marketPrice = getSafeFen(formData.marketPrice);
        formData.price = getSafeFen(formData.price);
        // 弹窗确认按钮loading
        setOperateLoadingLoading(true);
        try {
          const {
            code,
            data: newRecordId,
            message: msg,
          } = await addInventoryHistory(formData);
          if (code === ResponseCode.Success) {
            setModalConfig((config) => ({ ...config, visible: false }));
            actionRef.current?.reload();
            notification.success({
              message: `新增ID: ${newRecordId}成功`,
            });
          } else {
            notification.error({ message: msg || '新增失败' });
          }
        } catch (error: any) {
          notification.error({ message: error?.message || '新增失败' });
        }
        setOperateLoadingLoading(false);
        break;
      }
      // 修改时
      case 'edit': {
        const formData = await formInstance.validateFields();
        formData.marketPrice = getSafeFen(formData.marketPrice);
        formData.price = getSafeFen(formData.price);
        setOperateLoadingLoading(true);
        try {
          const { code, message: msg } = await updateInventoryHistory(
            modalConfig.recordId as number,
            formData,
          );
          if (code === ResponseCode.Success) {
            setModalConfig((config) => ({ ...config, visible: false }));
            actionRef.current?.reload();
            notification.success({ message: `更新成功` });
          } else {
            notification.error({ message: msg || '更新失败' });
          }
        } catch (error: any) {
          notification.error({ message: error?.message || '更新失败' });
        }
        setOperateLoadingLoading(false);
        break;
      }
      // 查看时
      case 'view':
        setModalConfig((config) => ({ ...config, visible: false }));
        break;
    }
  }

  return (
    <PageContainer className="user-management">
      <ProTable<InventoryHistoryRecord>
        columns={columns}
        actionRef={actionRef}
        request={async (params = {}, sort = {}) => {
          return request(params, sort);
        }}
        scroll={{
          x: 1400,
        }}
        rowKey="id"
        search={{
          labelWidth: 100,
          defaultCollapsed: false,
        }}
        pagination={{
          pageSize: 5,
        }}
        dateFormatter="string"
        toolBarRender={() => [
          <Button
            key="add-detail"
            icon={<PlusOutlined />}
            type="primary"
            onClick={() => {
              formInstance.resetFields();
              setModalConfig((config) => ({
                ...config,
                visible: true,
                type: 'add',
              }));
            }}
          >
            新增
          </Button>,
        ]}
      />
      <Modal
        title={MODAL_TITLE_MAP[modalConfig.type]}
        open={modalConfig.visible}
        onCancel={() =>
          setModalConfig((config) => ({
            ...config,
            visible: false,
            userId: undefined,
          }))
        }
        onOk={sureAdd}
        confirmLoading={operateLoading}
      >
        <Form
          labelCol={{ span: 5 }}
          form={formInstance}
          disabled={modalConfig.type === 'view'}
        >
          <Form.Item
            label="品牌选择"
            name="brandId"
            rules={DEFAULT_REQUIRED_RULE}
          >
            <DebounceSelect
              fetchOptions={fetchBrandList}
              showArrow={false}
              disabled={modalConfig.type === 'edit'}
              onChange={(value, option: any) => {
                formInstance.setFieldValue('lastBrandStock', option?.stock);
              }}
            />
          </Form.Item>
          <Form.Item
            shouldUpdate={shouldUpdateDependencies(['lastBrandStock'])}
            noStyle
          >
            {() => {
              const canBeToDelete =
                formInstance.getFieldValue('lastBrandStock') > 0;
              return (
                <Form.Item
                  label="出库/入库"
                  name="type"
                  rules={DEFAULT_REQUIRED_RULE}
                >
                  <Radio.Group
                    options={Object.keys(InventoryHistoryTypeMap).map(
                      (key) => ({
                        value: key,
                        label: InventoryHistoryTypeMap[key].text,
                        disabled:
                          key === InventoryHistoryType.Subtract &&
                          !canBeToDelete,
                      }),
                    )}
                  />
                </Form.Item>
              );
            }}
          </Form.Item>
          <Form.Item
            shouldUpdate={shouldUpdateDependencies(['lastBrandStock', 'type'])}
            noStyle
          >
            {() => {
              const isToSub =
                formInstance.getFieldValue('type') ===
                InventoryHistoryType.Subtract;
              const lastBrandStock =
                formInstance.getFieldValue('lastBrandStock');
              return (
                <Form.Item
                  name="nub"
                  label="总数量"
                  rules={DEFAULT_REQUIRED_RULE}
                >
                  <InputNumber
                    max={isToSub ? lastBrandStock : 100000}
                    min={1}
                    style={{ width: '100%' }}
                  />
                </Form.Item>
              );
            }}
          </Form.Item>
          <Form.Item name="price" label="总价格" rules={DEFAULT_REQUIRED_RULE}>
            <InputNumber
              max={10000}
              min={1}
              precision={2}
              style={{ width: '100%' }}
            />
          </Form.Item>
          <Form.Item name="marketPrice" label="当前市场单价">
            <InputNumber
              max={10000}
              min={1}
              precision={2}
              style={{ width: '100%' }}
            />
          </Form.Item>
          <Form.Item name="description" label="描述">
            <Input.TextArea rows={3} maxLength={256} showCount />
          </Form.Item>
          <Form.Item name="lastBrandStock" label="品牌库存" hidden>
            <Input />
          </Form.Item>
        </Form>
      </Modal>
    </PageContainer>
  );
};

export default InventoryHistoryManagement;
